
// 运算符映射：将公式中的符号映射到 PreciseDecimal 方法
// let Decimal;

// // 使用立即执行的异步函数处理动态导入
// (async () => {
//   try {
//     // 动态导入 decimal.js（返回模块对象）
//     const decimalModule = await import('decimal.js');
//     // 提取默认导出
//     Decimal = decimalModule.default;

//     // 仅在开发环境挂载到 window
//     const isDev = process.env.NODE_ENV === 'development' || import.meta.env.MODE === 'development';
//     if (isDev) {
//       window.Decimal = Decimal;
//     }
//   } catch (error) {
//     throw new Error('依赖 "decimal.js" 未找到，请执行 "npm install decimal.js" 安装后再使用本插件');
//   }
// })();




import Decimal from 'decimal.js'
// 先判断 import.meta.env 是否存在，避免 Node.js 环境报错
var isDev = process.env.NODE_ENV === 'development' || (import.meta.env && import.meta.env.MODE === 'development');
    // const isDev = process.env.NODE_ENV === 'development' || import.meta.env.MODE === 'development';
    if (isDev) {
      window.Decimal = Decimal;
    }

const getDecimalPrecision = (num) => {
  // 处理空值或非有效数字的情况
  if (num === null || num === undefined || Number.isNaN(Number(num))) {
    return 0;
  }

  // 将数字转为字符串（避免科学计数法影响）
  const numStr = typeof num === 'string' ? num : num.toString();

  // 检查是否包含小数点
  const dotIndex = numStr.indexOf('.');
  if (dotIndex === -1) {
    return 0; // 整数，精度为0
  }

  // 小数点后的部分即为小数位，长度就是精度
  return numStr.slice(dotIndex + 1).length;
};

const operatorMap = {
  '+': 'add',
  '-': 'sub',
  '*': 'mul',
  '/': 'div',
};

class PreciseDecimal {
  /**
   * @param {number|string|Decimal|PreciseDecimal|null} value - 数值
   * @param {number} [precision=20] - 精度
   * @param {Object} [options] - 配置项
   * @param {string} [options.curEditField] - 当前编辑的字段名（通过options传入）
   * @param {boolean} [options.ignorePrecision] - 是否忽略精度
   * @param {string[]} [options._ignoreNull] - 需要忽略null的字段列表
   */
  static precision = 2;

  constructor(value, precision, options = {}) {
    // 从options中获取当前编辑字段名
    this._curEditField = options.curEditField;

    // 解析其他配置项
    this._ignorePrecision = options.ignorePrecision || false;
    this._ignoreNull = options._ignoreNull || []; // 需要忽略的字段列表 暂时没有用到
    this._options = options;

    // 处理精度 --- 若是用户忽略精度 按照用户的当前值的精度来
    // this._precision = this._ignorePrecision ? PreciseDecimal.precision : precision ?? PreciseDecimal.precision;
    this._precision = this._ignorePrecision
      ? getDecimalPrecision(value)
      : (precision ?? PreciseDecimal.precision);

    // if (this._precision === 2) {
    //   console.log(
    //     { _value123: value },
    //     { _curEditField: this._curEditField },
    //     this._options,
    //     '我的套牢体爱你',
    //     this._ignorePrecision
    //       ? getDecimalPrecision(value)
    //       : (precision ?? PreciseDecimal.precision),
    //   );
    // }
    // 解析值（包含null处理）
    this._value = this._parseValue(value);
    // 记录原始值是否为null
    this._isOriginalNull = value === null;
  }

  // 解析输入值，处理null和忽略逻辑
  _parseValue(value) {
    // 判断条件：值为null 且 当前编辑字段在忽略列表中
    if (this._isOriginalNull && this._ignoreNull.includes(this._curEditField)) {
      return null; // 符合条件则返回null，不进行Decimal转换
    }

    // 处理PreciseDecimal实例
    if (value instanceof PreciseDecimal) {
      try {
        return new Decimal(value._value).toDecimalPlaces(this._precision);
      } catch (e) {
        return null;
      }
    }

    // 处理其他类型值
    try {
      return value !== null ? new Decimal(value).toDecimalPlaces(this._precision) : null;
    } catch (e) {
      return null;
    }
  }

  // 通用运算方法
  _operate(other, operator) {
    // 检查当前实例是否需要忽略
    const shouldIgnoreCurrent =
      this._isOriginalNull && this._ignoreNull.includes(this._curEditField);
    // 检查操作数是否需要忽略
    const otherDecimal = this._parseOperand(other);
    const shouldIgnoreOther =
      otherDecimal._isOriginalNull && otherDecimal._ignoreNull.includes(otherDecimal._curEditField);

    // 任何一方需要忽略，则返回null的PreciseDecimal实例
    if (shouldIgnoreCurrent || shouldIgnoreOther) {
      return new PreciseDecimal(null, this._precision, this._options);
    }

    // 计算结果精度
    const resultPrecision =
      this._ignorePrecision || otherDecimal._ignorePrecision ? this._precision : this._precision;

    // 执行运算
    let resultValue;
    try {
      if (operator && operatorMap[operator]) {
        resultValue = this._value[operatorMap[operator]](otherDecimal._value);
      } else {
        throw new Error(`未知运算符: ${operator}`);
      }
    } catch (error) {
      return new PreciseDecimal(null, this._precision, this._options);
    }

    // 此处不做精度计算, 精度应该在计算后手动按照计算后的值计算

    // console.log(
    //   'getDecimalPrecision(resultValue)',
    //   `resultValue====${resultValue}`,
    //   `精度:${getDecimalPrecision(resultValue)}`,
    // );
    return new PreciseDecimal(resultValue, getDecimalPrecision(resultValue), this._options);
    // return new PreciseDecimal(resultValue, resultPrecision, this._options);
  }

  // 运算方法
  add(other) {
    return this._operate(other, '+');
  }

  sub(other) {
    return this._operate(other, '-');
  }

  mul(other) {
    return this._operate(other, '*');
  }

  div(other) {
    return this._operate(other, '/');
  }

  // 解析操作数（确保为 PreciseDecimal 实例，传递options）
  _parseOperand(other) {
    if (other instanceof PreciseDecimal) {
      return other;
    }
    // 新建实例时传递当前options，保持上下文一致
    return new PreciseDecimal(other, this._precision, this._options);
  }

  toString() {
    if (this._isOriginalNull && this._ignoreNull.includes(this._curEditField)) {
      return 'null';
    }
    return this._ignorePrecision
      ? Number(this._value).toString()
      : this._value?.toFixed(this._precision) || '0';
  }

  toNumber(selfPrecision) {
    // 符合忽略条件时直接返回null
    if (this._isOriginalNull && this._ignoreNull.includes(this._curEditField)) {
      return null;
    }

    if (selfPrecision !== undefined) {
      return this._value ? Number(this._value.toFixed(selfPrecision)) : 0;
    }

    if (this._ignorePrecision) {
      return this._value ? Number(this._value) : 0;
    }

    return this._value ? Number(this._value.toFixed(this._precision)) : 0;
  }

  toValueOf() {
    if (this._isOriginalNull && this._ignoreNull.includes(this._curEditField)) {
      return null;
    }
    return this._value?.valueOf() || 0;
  }
}

export default PreciseDecimal;
